package com.sunpy.permissionservice.login.filter;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.sunpy.commonservice.util.JwtUtil;
import com.sunpy.commonservice.util.RedisCache;
import com.sunpy.permissionservice.login.model.LoginUserDetailBO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 *  动态权限
 */
@Slf4j
@Component
public class AuthorizeFilter implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private RedisCache redisCache;

    @Value("${sys.login-uri}")
    private String loginUri;

    @SneakyThrows
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) {
        log.info("+++++++++++++++++++AuthorizeFilter.getAttributes");
        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

        String jwt = request.getHeader("token");

        if (StrUtil.isBlank(jwt) && loginUri.equals(request.getRequestURI())) {
            return SecurityConfig.createList(loginUri);
        }


        String userId = (String) JwtUtil.parseJWT(jwt).get("userId");
        LoginUserDetailBO loginUserDetailBO = redisCache.getCacheObject("token:" + userId);
        List<String> authorityList = new ArrayList<>();
        loginUserDetailBO.getRoleBOList().forEach(roleBO -> {
            roleBO.getMenuBOList().forEach(menuBO -> {
                if (menuBO.getMenuUrl().equals(request.getRequestURI())) {
                    authorityList.add(menuBO.getMenuCode());
                }
            });
        });

        if (CollectionUtil.isEmpty(authorityList)) {
            return SecurityConfig.createList("UNAUTHORIZED");
        }

        String[] authorityArr = authorityList.toArray(new String[]{});
        return SecurityConfig.createList(authorityArr);
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
